package com.weiya.commons.util;

import cn.hutool.core.collection.CollectionUtil;
import com.weiya.commons.entity.NameValueDTO;
import com.weiya.commons.enums.EnumInterface;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * LocalEnumUtils枚举工具类,需要结合EnumInterface,操作的枚举均需要实现EnumInterface
 *
 * @author 奕超
 * @date 2018/5/8
 */
public class LocalEnumUtils {

    /**
     * 通过枚举name查找枚举对象
     */
    public static <E extends EnumInterface> E findByName(Class<E> enumClass, String name) {
        if (Objects.isNull(enumClass)) {
            return null;
        }
        for (E enumeration : enumClass.getEnumConstants()) {
            if (enumeration.name().equals(name)) {
                return enumeration;
            }
        }
        return getDefault(enumClass);
    }

    /**
     * 通过枚举name查找枚举对象
     */
    public static <E extends EnumInterface> E findByNameWithoutDefault(Class<E> enumClass, String name) {
        if (Objects.isNull(enumClass)) {
            return null;
        }
        for (E enumeration : enumClass.getEnumConstants()) {
            if (enumeration.name().equals(name)) {
                return enumeration;
            }
        }
        return null;
    }

    /**
     * 通过枚举code查找枚举对象
     *
     * @param <E> 所有继承枚举统一接口 EnumInterface
     * @return 查找到得枚举对象, 如果查不到将返回null
     */
    public static <E extends EnumInterface> E findByCode(Class<E> enumClass, Integer code) {
        if (Objects.isNull(enumClass)) {
            return null;
        }
        if (Objects.isNull(code)) {
            return getDefault(enumClass);
        }
        for (E enumeration : enumClass.getEnumConstants()) {
            if (enumeration.getCode().equals(code)) {
                return enumeration;
            }
        }
        return getDefault(enumClass);
    }

    /**
     * 通过枚举code查找枚举对象,不存在不返回default
     *
     * @param <E> 所有继承枚举统一接口 EnumInterface
     * @return 查找到得枚举对象, 如果查不到将返回null
     */
    public static <E extends EnumInterface> E findByCodeWithoutDefault(Class<E> enumClass,
            Integer code) {
        if (Objects.isNull(enumClass)) {
            return null;
        }
        if (Objects.isNull(code)) {
            return null;
        }
        for (E enumeration : enumClass.getEnumConstants()) {
            if (enumeration.getCode().equals(code)) {
                return enumeration;
            }
        }
        return null;
    }

    /**
     * 通过枚举desc获取枚举对象
     */
    public static <E extends EnumInterface> E findByDesc(Class<E> enumClass, String desc) {
        if (Objects.isNull(enumClass)) {
            return null;
        }
        for (E enumeration : enumClass.getEnumConstants()) {
            if (enumeration.getDesc().equals(desc)) {
                return enumeration;
            }
        }
        return getDefault(enumClass);
    }

    /**
     * 通过枚举desc获取枚举对象,不存在不返回default
     */
    public static <E extends EnumInterface> E findByDescWithoutDefault(Class<E> enumClass,
            String desc) {
        if (Objects.isNull(enumClass)) {
            return null;
        }
        for (E enumeration : enumClass.getEnumConstants()) {
            if (enumeration.getDesc().equals(desc)) {
                return enumeration;
            }
        }
        return null;
    }

    /**
     * 获取默认枚举
     */
    public static <E extends EnumInterface> E getDefault(Class<E> enumClass) {
        if (Objects.isNull(enumClass)) {
            return null;
        }
        E defaultEnu = null;
        for (E enumeration : enumClass.getEnumConstants()) {
            if (null != enumeration) {
                defaultEnu = (E) enumeration.getDefault();
                break;
            }
        }
        return defaultEnu;
    }

    /**
     * 根据code获取desc
     */
    public static <E extends EnumInterface> String getDescByCode(Class<E> enumClass, int code) {
        String desc = "";
        E e = findByCode(enumClass, code);
        if (null != e) {
            desc = e.getDesc();
        }
        return desc;
    }

    /**
     * 根据desc获取code,不采用default值
     */
    public static String getDescByEnum(EnumInterface e) {
        if (null == e) {
            return null;
        }
        return e.getDesc();
    }

    public static <E extends EnumInterface> List<NameValueDTO> getEnumCodeAndDesc(
            Class<E> enumClass) {
        if (Objects.isNull(enumClass)) {
            return null;
        }
        List<NameValueDTO> result = new ArrayList<>();
        for (E enu : enumClass.getEnumConstants()) {
            result.add(new NameValueDTO(enu.getDesc(), enu.getCode().toString()));
        }
        return result;
    }

    /**
     * 所有code是否都是正确的枚举
     *
     * @param enumClass
     * @param codeList
     * @param <E>
     * @return
     */
    public static <E extends EnumInterface> boolean containAllCode(Class<E> enumClass, List<Integer> codeList) {
        if(CollectionUtil.isEmpty(codeList) || Objects.isNull(enumClass)) {
            return false;
        }
        for (Integer code : codeList) {
            if(Objects.isNull(findByCodeWithoutDefault(enumClass, code))) {
                return false;
            }
        }
        return true;
    }

    public static <E extends EnumInterface> List<E> findByCodeList(Class<E> enumClass, List<Integer> codeList) {
        List<E> result = new ArrayList<>();
        if(CollectionUtil.isEmpty(codeList)) {
            return result;
        }
        for (Integer code : codeList) {
            E e = findByCodeWithoutDefault(enumClass, code);
            if(Objects.nonNull(e)) {
                result.add(e);
            }
        }
        return result;
    }

}
